//1. 泛型是具体类型或者其他属性的抽象替代，用于减少代码重复
// 2. 在函数定义中使用泛型
// 3. 在结构体中使用泛型
// 4. 枚举中的泛型
// 5. 方法中的泛型
// 6. 总结：使用泛型并不会造成程序性能上的损失。rust通过在编译时进行泛型代码的单态化来保证效率。单态化时通过填充编译时使用的具体类型，将通用代码转换为特定代码的过程。

//****************不用泛型********************************
//for i32
fn largest_i32(list:&[i32]) -> i32{
    let mut largest = list[0];
    for &item in list.iter() {
        if item > largest {
            largest = item;
        }
    }
    largest
}
//for char
fn largest_char(list:&[char]) -> char{
    let mut  largest = list[0];
    for &item in list.iter() {
        if item > largest {
            largest = item;
        }
    }
    largest
}

//***************使用泛型*************************
//函数中使用泛型。
// 泛型约束：PartialOrd能比较，Copy能copy
fn largest<T:PartialOrd + Copy>(list:&[T]) -> T{
    let mut largest = list[0];
    for &item in list.iter() {
        if item > largest {
            largest = item;
        }
    }
    largest
}

//在结构体中使用泛型
//x,y的类型需要相同
#[derive(Debug)]
struct Point<T>{
    x:T,
    y:T
}
#[derive(Debug)]
struct Point2<T,U>{
    x:T,
    y:U
}
//在枚举中使用泛型
enum Option<T>{
    Some(T),
    None
}
enum Result<T,E>{
    Ok(T),
    Err(E)
}

//在方法中使用泛型
struct Point3<T>{
    x:T,
    y:T
}

impl<T> Point3<T>{
    fn get_x(&self) -> &T{
        &self.x
    }
    fn get_y(&self) -> &T{
        &self.y
    }
}

fn main() {
    let number_list = vec![1,2,4,34,46,32,56];
    let max_number = largest_i32(&number_list);
    println!("max_number = {}",max_number);

    let char_list = vec!['a','b','c','z'];
    let max_char = largest_char(&char_list);
    println!("max_char = {}",max_char);

    //使用函数泛型
    let max_t = largest(&number_list);
    println!("max_t = {}",max_t);

    //使用结构体泛型
    let integer = Point{x:1,y:2};
    println!("integer = {:?}",integer);
    let float = Point{x:1.2,y:3.4};
    println!("float = {:#?}",float);

    let p = Point2{x:1.2,y:'a'};
    println!("p = {:?}",p);

    //在方法中使用泛型
    let p3 = Point3{x:1,y:3};
    println!("p3.x = {}",p3.get_x());
    println!("p3.y = {}",p3.get_y());

    println!("Hello, world!");
}
